// converting files in different formats

#ifndef RS_CONVERT_H
#define RS_CONVERT_H
#include <string>
#include "rs_table.h"
#include "rs_stream.h"
#include "rs_grammar.h"
#include "rs_token.h"
using namespace std;


enum file_format {
    ff_default,
    ff_text,
    ff_ispell,
    ff_po,
    ff_strings,
    ff_html,
    ff_dir
};

class converter {
public:
    converter (rs_grammar* rsg,
        const rs_string& src_og_name,
        const rs_string& tgt_og_name,
        bool show_unknown,
        bool allow_same=false);
    ~converter (void) {
        //rs_log_file (L"destructing converter: ", cnv_rsp.rsp_src_name + L"->" + cnv_rsp.rsp_tgt_name);
    }
    bool convert_file (const rs_string& in_fname, rs_string& out_fname, const rs_string& format, bool keep_to);
    bool convert_directory (const rs_string& in_dir, const rs_string& out_dir, bool keep_to);
    bool convert_directory (const rs_string& in_dir, const rs_string& out_dir, int level);
    bool is_valid () { return cnv_valid; };
private:
    rs_grammar* cnv_rsg;
    rs_pair cnv_rsp;
    rs_statistics cnv_stat;

    rs_istream* cnv_ifs;
    rs_ostream* cnv_ofs;
    rs_string   cnv_ofname; // file name of cnv_ofs
    bool cnv_valid;
    
    bool cnv_report_stat;
    bool cnv_dir;   // true when convert_directory is active
    bool cnv_keep_to; // true when the conversion of spelling checkers is to keep TO words

    void report_statistics();

    bool convert_any_word (const rs_string& src_word, rs_string& tgt_word);
    bool convert_article (const rs_string& src, rs_string& cnv, const wd_mode& wdm);
    void convert_po_file   ();
    void convert_strings_file ();
    void convert_text_file ();
    void convert_ispell_file ();
    void create_ispell_hash (const rs_string& dict_fname, 
        const rs_string& ispell_aff_fname,
        const rs_string& hash_fname);
    void convert_html_file ();

    bool close_files ();
    bool init_open_files (const rs_string& in_fname, rs_string& out_fname, bool skip_input_output=false);
    void update_out_fname (const rs_string& in_fname, rs_string& out_fname);
};


class converter_factory {
public:
    converter_factory () {cf_grammar=0;};
    ~converter_factory () {
        if (cf_grammar) {
            delete cf_grammar;
            cf_grammar=0;
        }
    };
    converter& get_converter (
        const rs_string& src_og_name,
        const rs_string& tgt_og_name,
        const rs_string& affix_cg_fname,
        const rs_string& proper_lc_fname,
        bool show_unknown,
        bool allow_same=false);
private:
    rs_grammar* cf_grammar;
};


#endif
